package com.punch.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.user.guardian.AppSaveStudentDTO;
import com.punch.common.dto.user.guardian.GuardianStudentDTO;
import com.punch.common.dto.user.user.RedisUserDTO;
import com.punch.common.exception.BusinessException;
import com.punch.common.feign.FeignClassService;
import com.punch.common.simple.redis.utils.UserUtil;
import com.punch.common.utils.ImageUtil;
import com.punch.common.vo.user.guardian.GuardianStudentVO;
import com.punch.common.vo.user.guardian.SimpleStudentVO;
import com.punch.common.vo.user.student.StudentVO;
import com.punch.user.exception.UserExceptionEnum;
import com.punch.user.mapper.SysGuardianStudentMapper;
import com.punch.user.mapper.SysUserMapper;
import com.punch.user.mapper.SysUserSchoolMapper;
import com.punch.user.model.*;
import com.punch.user.service.GuardianStudentService;
import com.punch.user.service.PlatformUserService;
import com.punch.user.service.StudentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;


/**
 * @author Liang
 */
@Service
public class GuardianStudentServiceImpl extends ServiceImpl<SysGuardianStudentMapper, SysGuardianStudent> implements GuardianStudentService {

    @Resource
    private StudentService studentService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserSchoolMapper sysUserSchoolMapper;

    @Resource
    private FeignClassService feignClassService;

    @Resource
    private PlatformUserService platformUserService;


    /**
     * 保存家长选的学生信息
     *
     * @param guardianStudentDTO 家长学生表单
     * @return 新增返回的记录ID
     */
    @Override
    public Long saveGuardianStudent(GuardianStudentDTO guardianStudentDTO) {
        //获取学生信息
        SysStudent sysStudentEX = studentService.getById(guardianStudentDTO.getStudentId());
        if (sysStudentEX == null) {
            throw new BusinessException(UserExceptionEnum.STUDENT_NOT_EXIST);
        }
        //如果家长已经添加学生则不能再添加
        QueryWrapper<SysGuardianStudent> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysGuardianStudent::getGuardianId, UserUtil.getLoginUserId())
                .eq(SysGuardianStudent::getStudentId, guardianStudentDTO.getStudentId());
        SysGuardianStudent parentStudentEX = getOne(queryWrapper);
        if (parentStudentEX != null) {
            throw new BusinessException(UserExceptionEnum.HAVE_ADD_THIS_STUDEN);
        }
        SysGuardianStudent sysGuardianStudent = new SysGuardianStudent();
        // sysGuardianStudent.setDefaultFlag(guardianStudentDTO.getDefaultFlag());
        sysGuardianStudent.setGuardianId(UserUtil.getLoginUserId());
        sysGuardianStudent.setStudentId(guardianStudentDTO.getStudentId());
        boolean flag = save(sysGuardianStudent);
        if (!flag) {
            throw new BusinessException(UserExceptionEnum.DATA_INSERT_EXCEPTION);
        }
        return sysGuardianStudent.getId();
    }

    /**
     * 家长已添加学生列表
     *
     * @return GuardianStudentVO 学生列表
     */
    @Override
    public List<GuardianStudentVO> listGuardianStudent() {
        Long userId = UserUtil.getLoginUserId();
        List<GuardianStudentVO> retList = getBaseMapper().selectGuardianStudent(userId);
        retList.forEach(this::accept);
        return retList;
    }


    private void accept(GuardianStudentVO guardianStudentVO) {
        //出勤率
        Double attendanceRate = feignClassService.attendanceRate(guardianStudentVO.getStudentId(), guardianStudentVO.getAreaId());
        guardianStudentVO.setAttendanceRate(attendanceRate);
        guardianStudentVO.setAvatar(ImageUtil.addPrefix(guardianStudentVO.getAvatar()));
    }

    /**
     * 删除家长选的学生信息
     *
     * @param studentId 学生id
     */
    @Override
    public void deleteGuardianStudent(Long studentId) {
        //断学生是否有订单 todo
        UpdateWrapper<SysGuardianStudent> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(SysGuardianStudent::getGuardianId, UserUtil.getLoginUserId())
                .eq(SysGuardianStudent::getStudentId, studentId);
        if (!remove(updateWrapper)) {
            throw new BusinessException(UserExceptionEnum.DATA_DELETION_EXCEPTION);
        }
    }

    /**
     * 保存家长选的学生信息
     *
     * @param appSaveStudentDTO 保存信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveStudent(AppSaveStudentDTO appSaveStudentDTO) {
        Long schoolId = appSaveStudentDTO.getSchoolId();
        SysUser school = sysUserMapper.selectById(schoolId);
        Optional.ofNullable(school).orElseThrow(() -> new BusinessException(UserExceptionEnum.SCHOOL_NOT_EXIST));
        QueryWrapper<SysUserSchool> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserSchool::getUserId, schoolId);
        SysUserSchool sysUserSchool = sysUserSchoolMapper.selectOne(queryWrapper);
        Optional.ofNullable(sysUserSchool).orElseThrow(() -> new BusinessException(UserExceptionEnum.SCHOOL_NOT_EXIST));
        //查看学校添加学生方式
        if (sysUserSchool.getAddStuType() == 0) {
            //学校已经添加该学生,家长进行绑定,插入sys_guardian_student表,没有该学生则抛出异常
            bindStudent(appSaveStudentDTO);
        }

        if (sysUserSchool.getAddStuType() == 1) {
            //学校已经添加该学生,家长进行绑定,插入sys_guardian_student表,没有该学生则抛出异常
            platformUserSaveStudent(appSaveStudentDTO, school.getUsername(), school.getAreaId(), school.getAreaName());
        }
    }

    /**
     * App端家长修改学生信息
     *
     * @param guardianStudentDTO 编辑信息
     */
    @Override
    public void updateGuardianStudent(GuardianStudentDTO guardianStudentDTO) {
        Long studentId = guardianStudentDTO.getStudentId();
        SysStudent studentEX = studentService.getById(studentId);
        Optional.ofNullable(studentEX).orElseThrow(() -> new BusinessException(UserExceptionEnum.STUDENT_NOT_EXIST));
        //由学校添加的学生只能修改头像
        if (studentEX.getAddStuType() == 0) {
            SysStudent sysStudent = new SysStudent();
            sysStudent.setAvatar(ImageUtil.removePrefix(guardianStudentDTO.getAvatar()));
            sysStudent.setId(studentId);
            studentService.updateById(sysStudent);
        }
        //家长自己添加的学生可以修改除学校外其余信息
        if (studentEX.getAddStuType() == 1) {
            SysStudent sysStudent = new SysStudent();
            BeanUtil.copyProperties(guardianStudentDTO, sysStudent);
            //修改头像
            sysStudent.setAvatar(ImageUtil.removePrefix(guardianStudentDTO.getAvatar()));
            sysStudent.setName(guardianStudentDTO.getStudentName());
            sysStudent.setAvatar("");//设置学生默认头像
            sysStudent.setId(studentId);
            studentService.updateById(sysStudent);
        }

    }

    /**
     * 根据id查询学生信息
     *
     * @param userId    用户uid
     * @param studentId 学生id
     * @return StudentVO
     */
    @Override
    public StudentVO getFeignStudentById(Long userId, Long studentId) {
        return getBaseMapper().selectStudent(userId, studentId);
    }

    /**
     * 简单学生列表
     *
     * @return List<SimpleStudentVO>
     */
    @Override
    public List<SimpleStudentVO> listSimpleStudent() {
        Long userId = UserUtil.getLoginUserId();
        List<SimpleStudentVO> retList = getBaseMapper().selectSimpleStudent(userId);
        return retList;
    }

    /**
     * 家长绑定学生
     *
     * @param appSaveStudentDTO 学生表单
     */
    private void bindStudent(AppSaveStudentDTO appSaveStudentDTO) {
        QueryWrapper<SysStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda().eq(SysStudent::getCreateId, appSaveStudentDTO.getSchoolId())
                .eq(SysStudent::getGradeYear, appSaveStudentDTO.getGradeYear())
                .eq(SysStudent::getGradeClass, appSaveStudentDTO.getGradeClass())
                .eq(SysStudent::getName, appSaveStudentDTO.getStudentName())
                .eq(SysStudent::getSex, appSaveStudentDTO.getSex());
        studentQueryWrapper.last(" limit 1");
        SysStudent sysStudentEX = studentService.getOne(studentQueryWrapper);
        Optional.ofNullable(sysStudentEX).orElseThrow(() -> new BusinessException(UserExceptionEnum.STUDENT_NOT_IN_SCHOOL));
        Long userId = UserUtil.getLoginUserId();
        //查看是否已保存,如果已保存则不添加
        QueryWrapper<SysGuardianStudent> guardianStudentQueryWrapper = new QueryWrapper<>();
        guardianStudentQueryWrapper.lambda().eq(SysGuardianStudent::getGuardianId, userId)
                .eq(SysGuardianStudent::getSchoolId, appSaveStudentDTO.getSchoolId())
                .eq(SysGuardianStudent::getStudentId, sysStudentEX.getId());
        if (count(guardianStudentQueryWrapper) > 0) {
            //说明已经绑定过该学生
            throw new BusinessException(UserExceptionEnum.HAVE_ADD_THIS_STUDEN);
        }
        //保存关联关系
        SysGuardianStudent sysGuardianStudent = new SysGuardianStudent();
        sysGuardianStudent.setStudentId(sysStudentEX.getId());
        sysGuardianStudent.setGuardianId(userId);
        sysGuardianStudent.setSchoolId(appSaveStudentDTO.getSchoolId());
        save(sysGuardianStudent);
    }


    /**
     * 家长自行添加学生
     *
     * @param appSaveStudentDTO 学生表单
     */
    private void platformUserSaveStudent(AppSaveStudentDTO appSaveStudentDTO, String schoolName, Integer areaId, String areaName) {
        RedisUserDTO loginUser = UserUtil.getLoginUser();
        SysStudent sysStudent = new SysStudent();
        sysStudent.setName(appSaveStudentDTO.getStudentName());
        sysStudent.setGradeYear(appSaveStudentDTO.getGradeYear());
        sysStudent.setGradeClass(appSaveStudentDTO.getGradeClass());
        //获取家长手机
        PlatformUser platformUser = platformUserService.getById(UserUtil.getLoginUserId());
        Optional.ofNullable(platformUser).orElseThrow(() -> new BusinessException(UserExceptionEnum.APP_USER_NOT_EXIST));
        sysStudent.setGuardianMobile(platformUser.getMobile());
        sysStudent.setAddStuType(1);
        sysStudent.setSex(appSaveStudentDTO.getSex());
        sysStudent.setAreaId(areaId);
        sysStudent.setAreaName(areaName);
        sysStudent.setCreateId(appSaveStudentDTO.getSchoolId());
        sysStudent.setSchoolName(schoolName);
        //设置学生默认头像
        //女生
        if (0 == appSaveStudentDTO.getSex()) {
            sysStudent.setAvatar("/default/student/default_student_girl.png");
        }
        //男生
        if (1 == appSaveStudentDTO.getSex()) {
            sysStudent.setAvatar("/default/student/default_student_boy.png");
        }
        studentService.save(sysStudent);
        //保存关联关系
        SysGuardianStudent sysGuardianStudent = new SysGuardianStudent();
        sysGuardianStudent.setStudentId(sysStudent.getId());
        sysGuardianStudent.setGuardianId(loginUser.getUserId());
        sysGuardianStudent.setSchoolId(appSaveStudentDTO.getSchoolId());
        sysGuardianStudent.setAddStuType(1);
        save(sysGuardianStudent);
    }

}
